package com.kg.tombs.controller;

import com.kg.tombs.db.MongoVerticle;
import com.kg.tombs.service.Neo4jService;
import com.kg.tombs.utils.CsvParser;
import com.kg.tombs.utils.ExcelParser;
import com.kg.tombs.utils.PinyinUtils;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.FileUpload;
import io.vertx.ext.web.RoutingContext;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Slf4j
public class ExcelController {

    private final Vertx vertx;

    private final MongoVerticle mongoVerticle;

    private final Neo4jService neo4jService;

    public ExcelController(Vertx vertx,MongoVerticle mongoVerticle) {
        this.vertx = vertx;
        this.mongoVerticle = mongoVerticle;
        this.neo4jService = new Neo4jService(vertx, mongoVerticle);
    }

    public void upload(RoutingContext ctx) {
        List<FileUpload> fileUploads = ctx.fileUploads();

        if (fileUploads.isEmpty()) {
            ctx.response()
                    .setStatusCode(400)
                    .end("No files uploaded");
            return;
        }

        for (FileUpload fileUpload : fileUploads) {
            if (isExcelFile(fileUpload)) {
                // 处理Excel文件的现有逻辑
                processExcelFile(ctx, fileUpload, fileUploads);
            } else if (isCsvFile(fileUpload)) {
                // 处理CSV文件的新逻辑
                processCsvFile(ctx, fileUpload, fileUploads);
            } else {
                ctx.response()
                        .setStatusCode(400)
                        .end("Invalid file type. Only Excel and CSV files are allowed.");
                return;
            }
        }
    }


    private void processExcelFile(RoutingContext ctx, FileUpload fileUpload, List<FileUpload> fileUploads) {
        vertx.fileSystem().readFile(fileUpload.uploadedFileName())
                .onSuccess(buffer -> {
                    try (InputStream is = new ByteArrayInputStream(buffer.getBytes())) {
                        String fileNameWithoutExtension = getFileNameWithoutExtension(fileUpload.fileName());

                        List<JsonObject> parse = ExcelParser.parse(is);
                        saveData(ctx, parse, fileNameWithoutExtension, fileUploads, fileUpload);
                    } catch (IOException e) {
                        handleError(ctx, "Error processing file: " + e.getMessage());
                    }
                })
                .onFailure(cause -> {
                    handleError(ctx, "Failed to read file: " + cause.getMessage());
                });
    }

    private void processCsvFile(RoutingContext ctx, FileUpload fileUpload, List<FileUpload> fileUploads) {
        vertx.fileSystem().readFile(fileUpload.uploadedFileName())
                .onSuccess(buffer -> {
                    try (InputStream is = new ByteArrayInputStream(buffer.getBytes())) {
                        String fileNameWithoutExtension = getFileNameWithoutExtension(fileUpload.fileName());

                        // 需要实现CSV解析器
                        List<JsonObject> parse = CsvParser.parse(is);
                        saveData(ctx, parse, fileNameWithoutExtension, fileUploads, fileUpload);
                    } catch (Exception e) {
                        handleError(ctx, "Error processing CSV file: " + e.getMessage());
                    }
                })
                .onFailure(cause -> {
                    handleError(ctx, "Failed to read file: " + cause.getMessage());
                });
    }

    /**
     * 验证是否为Excel文件
     */
    private boolean isExcelFile(FileUpload fileUpload) {
        String contentType = fileUpload.contentType();
        String fileName = fileUpload.fileName();

        // 检查content type
        if ("application/vnd.ms-excel".equals(contentType) ||
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(contentType)) {
            return true;
        }

        // 检查文件扩展名作为备用验证
        return fileName.endsWith(".xls") || fileName.endsWith(".xlsx");
    }

    /**
     * 验证是否为CSV文件
     */
    private boolean isCsvFile(FileUpload fileUpload) {
        String contentType = fileUpload.contentType();
        String fileName = fileUpload.fileName();

        // 检查content type
        if ("text/csv".equals(contentType) || "application/csv".equals(contentType)) {
            return true;
        }

        // 检查文件扩展名作为备用验证
        return fileName.endsWith(".csv");
    }

    /**
     * 提取无扩展名的文件名
     */
    private String getFileNameWithoutExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex > 0) {
            fileName = fileName.substring(0, dotIndex);
        }
        return fileName.replaceAll("\\s+", "");
    }

    private boolean saveData(RoutingContext ctx, List<JsonObject> parse,String fileNameWithoutExtension,List<FileUpload> fileUploads,FileUpload fileUpload) {
        log.info("parseCount:{}", parse.size());
        mongoVerticle.dropCollection(fileNameWithoutExtension);
        mongoVerticle.insertMany(fileNameWithoutExtension, parse);
        String dataBaseName = PinyinUtils.toValidDatabaseName(fileNameWithoutExtension);
        neo4jService.clearDataSet(dataBaseName)
                .flatMap(v -> neo4jService.save(parse, dataBaseName))
                .onSuccess(v -> {
                    if (fileUploads.indexOf(fileUpload) == fileUploads.size() - 1) {
                        ctx.response()
                                .setStatusCode(200)
                                .end("Files uploaded successfully");
                    }
                })
                .onFailure(cause -> {
                    handleError(ctx, "Failed to read file: " + cause.getMessage());
                });
        return false;
    }

    /**
     * 统一错误处理
     */
    private void handleError(RoutingContext ctx, String errorMessage) {
        if (!ctx.response().ended()) {
            ctx.response()
                    .setStatusCode(500)
                    .end(errorMessage);
        }
    }

}
